#pragma once

// Dependencies
#include <iostream>
#include "Vector2.h"

// Writes and reads Vector2s in the form of "<x, y>"
template<class T>
std::ostream& operator << ( std::ostream& out, const Vector2_t<T>& vec ) {
	return out << '<' << vec.x << ", " << vec.y << '>';
}

template<class T>
std::istream& operator >> ( std::istream& in, Vector2_t<T>& vec ) {
	int dummy[3];
	in >> dummy[0] >> vec.x >> dummy[1] >> vec.y >> dummy[2];
	if ( in && dummy[0] == '<' && dummy[1] == ',' && dummy[2] == '>' )
		return in;
	in.setstate(std::ios::badbit);
	return in;
}

/*
// Formatter namespace
// (TODO: Testing this design; any good?)
// A group of insertion and extraction operator overloads to format a Vector2 in different ways
// To use:  Use the specific namespace (Text/Simple/Binary) in the scope you wish to perform Vector2 insertions/extractions.
// (See ReflectionTests.cpp for an example)
namespace Formatter { 
	namespace Text {
		// Writes and reads Vector2s in the form of "<x, y>"
		template<class T>
		std::ostream& operator << ( std::ostream& out, const Vector2_t<T>& vec ) {
			return out << '<' << vec.x << ", " << vec.y << '>';
		}

		template<class T>
		std::istream& operator >> ( std::istream& in, Vector2_t<T>& vec ) {
			int dummy[3];
			in >> dummy[0] >> vec.x >> dummy[1] >> vec.y >> dummy[2];
			if ( in && dummy[0] == '<' && dummy[1] == ',' && dummy[2] == '>' )
				return in;
			in.setstate(std::ios::badbit);
			return in;
		}
	}

	namespace Simple {
		// Reads and writes Vector2s in the form of "x y"
		template<class T>
		std::ostream& operator << ( std::ostream& out, const Vector2_t<T>& vec ) {
			return out << vec.x << ' ' << vec.y;
		}

		template<class T>
		std::istream& operator >> ( std::istream& in, Vector2_t<T>& vec ) {			
			return in >> vec.x >> vec.y;
		}
	}

	namespace Binary {
		// Reads and writes Vector2s in their binary form
		template<class T>
		std::ostream& operator << ( std::ostream& out, const Vector2_t<T>& vec ) {
			out.write( reinterpret_cast<const char*>(&vec), sizeof(vec) );
			return out;
		}

		template<class T>
		std::istream& operator >> ( std::istream& in, Vector2_t<T>& vec ) {
			in.read( reinterpret_cast<char*>(&vec), sizeof(vec) );
			return in;
		}
	}
}
*/